﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;

namespace NHTrace.Tests
{
  [TestFixture]
  public class SqlParameterParserTests
  {
    [Test]
    public void GetParametersTest_LastParameterWithCommas()
    {
      const string STR_SqlStatement = "NHibernate: INSERT INTO \"Product\" (Name, UnitPrice, Discontinued, Id, Name2) " +
        "VALUES (@p0, @p1, @p2, @p3, @p4);@p0 = 'Apple0, Apple1, Apple2', @p1 = 0.25, @p2 = False, @p3 = 1001, @p4 = 'Apple3, Apple4, Apple5'";

      var parser = new SqlParameterParser();
      var parameters = parser.GetParameters(STR_SqlStatement);

      Assert.AreEqual(5, parameters.Count);

      Assert.IsTrue(parameters.ContainsKey("@p0"));
      Assert.AreEqual("'Apple0, Apple1, Apple2'", parameters["@p0"]);

      Assert.IsTrue(parameters.ContainsKey("@p1"));
      Assert.AreEqual("0.25", parameters["@p1"]);

      Assert.IsTrue(parameters.ContainsKey("@p2"));
      Assert.AreEqual("False", parameters["@p2"]);

      Assert.IsTrue(parameters.ContainsKey("@p3"));
      Assert.AreEqual("1001", parameters["@p3"]);

      Assert.IsTrue(parameters.ContainsKey("@p4"));
      Assert.AreEqual("'Apple3, Apple4, Apple5'", parameters["@p4"]);
    }

    [Test]
    public void GetParametersTest_LastParameterWithoutCommas()
    {
      const string STR_SqlStatement = "NHibernate: INSERT INTO \"Product\" (Name, UnitPrice, Discontinued, Id, Name2) " +
        "VALUES (@p0, @p1, @p2, @p3, @p4);@p0 = 'Apple0, Apple1, Apple2', @p1 = 0.25, @p2 = False, @p3 = 1001, @p4 = 'Apple3'";

      var parser = new SqlParameterParser();
      var parameters = parser.GetParameters(STR_SqlStatement);

      Assert.AreEqual(5, parameters.Count);

      Assert.IsTrue(parameters.ContainsKey("@p0"));
      Assert.AreEqual("'Apple0, Apple1, Apple2'", parameters["@p0"]);

      Assert.IsTrue(parameters.ContainsKey("@p1"));
      Assert.AreEqual("0.25", parameters["@p1"]);

      Assert.IsTrue(parameters.ContainsKey("@p2"));
      Assert.AreEqual("False", parameters["@p2"]);

      Assert.IsTrue(parameters.ContainsKey("@p3"));
      Assert.AreEqual("1001", parameters["@p3"]);

      Assert.IsTrue(parameters.ContainsKey("@p4"));
      Assert.AreEqual("'Apple3'", parameters["@p4"]);
    }

    [Test]
    public void GetParametersTest_StatementWithNoParameters()
    {
      const string STR_SqlStatement = "NHibernate: INSERT INTO \"Product\" (Name, UnitPrice, Discontinued, Id) " +
        "VALUES ('Apple0, Apple1, Apple2', 0.25, False, 1001);";

      var parser = new SqlParameterParser();
      var parameters = parser.GetParameters(STR_SqlStatement);

      Assert.AreEqual(0, parameters.Count);
    }

    [Test]
    public void GetParametersTest_StatementWithOneParameter()
    {
      const string STR_SqlStatement = "NHibernate: INSERT INTO \"Product\" (Name, UnitPrice, Discontinued, Id) " +
        "VALUES ('Apple0, Apple1, Apple2', 0.25, False, @p0);@p0 = 1001";

      var parser = new SqlParameterParser();
      var parameters = parser.GetParameters(STR_SqlStatement);

      Assert.AreEqual(1, parameters.Count);

      Assert.IsTrue(parameters.ContainsKey("@p0"));
      Assert.AreEqual("1001", parameters["@p0"]);
    }

    [Test]
    public void GetParametersTest_StatementIsInvalidSql()
    {
      const string STR_SqlStatement = "some simple no sql text";

      var parser = new SqlParameterParser();
      var parameters = parser.GetParameters(STR_SqlStatement);

      Assert.AreEqual(0, parameters.Count);
    }

    [Test]
    public void GetParametersTest_StatementWithMoreThan10Parameters()
    {
      const string STR_SqlStatement = "NHibernate: INSERT INTO \"Product\" (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11) " +
        "VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11);" +
        "@p0 = 'p0', @p1 = 'p1', @p2 = 'p2', @p3 = 'p3', @p4 = 'p4', @p5 = 'p5', @p6 = 'p6', @p7 = 'p7', @p8 = 'p8', @p9 = 'p9', @p10 = 'p10', @p11 = 'p11'";

      var parser = new SqlParameterParser();
      var parameters = parser.GetParameters(STR_SqlStatement);

      Assert.AreEqual(12, parameters.Count);

      for (int i = 0; i <= 11; i++)
      {
        var aux = "p" + i.ToString();
        Assert.IsTrue(parameters.ContainsKey("@" + aux));
        Assert.AreEqual("'" + aux + "'", parameters["@" + aux]);
      }
    }

  }
}
